package com.hxk.juc.prodCons;

/**
 * 生产者和消费者多线精简案例（使用synchronized+wait+notifyAll实现）
 * 题目：现有两个线程，操作初始值为0的一个变量，
 *      实现一个线程对他加1，一个线程对他減1的操作，
 *      实现交替，来10轮，变量初始值为0
 *  实现思想：
 *  1、在高并发的情况下，线程操作资源类
 *  2、判断/操作/通知
 */
public class ProdConsumerCase {

    public static void main(String[] args) {
        Resources resources = new Resources();

        new Thread(()->{
            for (int i = 1; i <= 10; i++) {
                try {
                    resources.incr();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"A").start();

        new Thread(()->{
            for (int i = 1; i <= 10; i++) {
                try {
                    resources.decr();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
    }
}

/**
 * 资源类
 */
class Resources{

    //要被线程操作的变量
    private int num = 0;

    /**
     * 生产方法
     * @throws Exception
     */
    public synchronized void incr() throws Exception{
        while (num != 0){//此处是一个坑点，在使用synchronized+wait+notifyAll线程间通信时，wait方法的判断不能使用if必须使用while，不然会出现虚假唤醒
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+"\t  生产："+num);
        this.notifyAll();
    }

    /**
     * 消费方法
     * @throws Exception
     */
    public synchronized void decr() throws Exception{
        while (num == 0){
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+"\t  消费："+num);
        this.notifyAll();
    }
}
